package com.caits.lbs.framework.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import com.caits.lbs.framework.Constants;
import com.caits.lbs.framework.controller.BaseController;
import com.caits.lbs.framework.listener.CustomizedPropertyConfigurer;
import com.caits.lbs.framework.utils.CollectionUtils;
import com.caits.lbs.framework.utils.HttpUtils;
import com.caits.lbs.framework.utils.ServletUtils;
import com.caits.lbs.framework.utils.StringUtils;

/**
 * <p>
 * LoginFilter
 * </p>
 * <p>
 * 登录验证过滤器，允许部分请求通过
 * </p>
 * @author 周华彬(zhouhuabin@sinoiov.com, zhou_hua_bin@163.com)
 * @version 0.0.0
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>admin</td>
 *          <td>2017年6月23日 下午2:49:00</td>
 *          </tr>
 *          <tr>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          </tr>
 *          </table>
 */
public class LoginFilter implements Filter {
	/** 变量:日志记录器,类型:Log */
	private org.apache.logging.log4j.Logger LOG = LogManager.getLogger(getClass());
	private String[] allowDomains = {"http://10.0.0.100:9099","http://home.ngrok.hayll.cn","https://www.hayll.cn","http://zhouhuabin.com","http://zhoupan.com","http://localhost:8080","http://localhost:9090","http://127.0.0.1:1314"};
    private List<String> allowDomainList = new ArrayList<>();
	
	/* (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		String uri = ServletUtils.getUri(req);
		//LOG.info("values:"+ServletUtils.getParameterValues(req));
		String requestParam =StringUtils.null2blank(ServletUtils.getParameterValues(req));
		int printLength = Math.min(requestParam.length(), Constants.Common.LOGOUT_MAXLENGTH);
		LOG.info("收到请求 url:" + uri + "?" + requestParam.substring(0, printLength) + ",client=" + HttpUtils.getClientIpAddr(req));
//		Enumeration<String> headers = req.getHeaderNames();
//		while(headers.hasMoreElements()) {
//			String headName = headers.nextElement();
//			String headValue = req.getHeader(headName);
//			LOG.info("获取到 headName:{},headValue:{}" ,headName,headValue);
//		}
		String originHeader = req.getHeader("Origin");
        if (allowDomainList.contains(originHeader))
        {
            resp.setHeader("Access-Control-Allow-Origin", originHeader);
            resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    		resp.setHeader("Access-Control-Max-Age", "86400");
    		resp.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
    		resp.setHeader("Access-Control-Allow-Credentials", "true");
    		resp.setHeader("XDomainRequestAllowed", "1");
        }

		String method = req.getMethod();
		// 最外层过滤，暂时没有约束
		if ("OPTIONS".equalsIgnoreCase(method)) {
			writeJsonResponse((HttpServletResponse) response);
		} else {
			chain.doFilter(request, response);
		}
	}

	/**
	 * 输出options内容到客户端 
	 * @param response 
	 * @return 返回void
	 */
	private void writeJsonResponse(HttpServletResponse response) {
		try {
			response.setContentType(BaseController.ContentTypeJsonUtf8);
			String returnValue = "{\"status\":\"OK\"}";
			response.getWriter().println(returnValue);
			response.getWriter().flush();
			byte[] returnData = returnValue.getBytes(BaseController.CHARSET_UTF8);
			response.setContentLength(returnData.length);
			LOG.info("options请求直接返回OK");
		} catch (IOException e) {
			LOG.error("返回客户端数据异常,msg=" + e.getLocalizedMessage(), e);
		}
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		for(String domain:allowDomains){
			allowDomainList.add(domain);
		}
		
		if(!CollectionUtils.isEmpty(CustomizedPropertyConfigurer.getAllowDomainList())){
			LOG.info("获取到补充的跨域地址size:{}",CustomizedPropertyConfigurer.getAllowDomainList().size());
			allowDomainList.addAll(CustomizedPropertyConfigurer.getAllowDomainList());
		}
	}
}
